package com.kgis.map.geometry.basetype {
   import com.kgis.map.projection.Projection;
   import com.kgis.map.projection.ProjectionPoint;
   import com.kgis.map.projection.ProjectionTransform;

   /**
    * location (x,y)  地理坐标点
    */
   public class Location {
      private var _projection:Projection = null;
      private var _x:Number;
      private var _y:Number;

      /**
       * Constructor
       * @param x:Number the X coordinate of the location
       * @param y:Number the Y coordinate of the location
       * @param proj:ProjProjection the projection of the coordinates, default EPSG:4326
       */
      public function Location(x:Number, y:Number, proj:Projection = null) {
         this._x = x;
         this._y = y;
/*         if (proj == null) {
            this._projection = Projection.getProjProjection("EPSG:4326");
         }
         else {
            this._projection = proj;
         }*/
      }

      /**
       * getter for the ProjProjection of the Location
       *
       * @return ProjProjection the ProjProjection of the Location
       */
      public function get projection():Projection {
         return this._projection;
      }

      /**
       * Clone the current location
       *
       * @return IProjectable a clone of the current location
       */
      public function clone():Location {
         return new Location(this._x, this._y, this._projection);
      }

      /**
       * getter for x coordinate of the Location
       *
       * @return Number the x coordinate
       */
      public function get x():Number {
         return this._x;
      }

      public function set x(x:Number):void {
         this._x = x;
      }

      /**
       * getter for Y coordinate of the Location
       *
       * @return Number the y coordinate
       */
      public function get y():Number {
         return this._y;
      }

      public function set y(y:Number):void {
         this._y = y;
      }

      /**
       * getter for lon coordinate of the Location
       *
       * @return Number the lon coordinate
       */
      public function get lon():Number {
         return this._x;
      }

      /**
       * getter for lat coordinate of the Location
       *
       * @return Number the lat coordinate
       */
      public function get lat():Number {
         return this._y;
      }

      /**
       * Reproject the current location in another ProjProjection
       *
       * @param oldProj:ProjProjection the source projection
       * @param newProj:ProjProjection the target projection
       *
       * @return Location the equivalent Location of this location in the new ProjProjection
       */
      public function reprojectTo(oldProj:Projection , newProj:Projection):Location {
         if (oldProj == null || newProj == null) {
            return this;
         }

         if (newProj.srsCode == oldProj.srsCode) {
            return this;
         }
         var p:ProjectionPoint = new ProjectionPoint(this._x, this._y);
         ProjectionTransform.transform(oldProj, newProj, p);

         return new Location(p.x, p.y, newProj);
      }

      /**
       * give the equivalent string of the current location
       *
       * @return String the current location
       */
      public function toString():String {
         return "lon=" + this._x + ",lat=" + this._y;
      }

      /**
       * give the equivalent short string of the current location
       *
       * @return String the current location
       */
      public function toShortString():String {
         return this._x + ", " + this._y;
      }

      /**
       * add delta derivation to the current Location
       *
       * @param x:Number the X derivation
       * @param y:Number the Y derivation
       *
       * @return Location the new Location
       */
      public function add(x:Number, y:Number):Location {
         return new Location(this._x + x, this._y + y, this._projection);
      }

      /**
       * compare a Location with the current one
       *
       * @param loc:Location the Location to compare with
       *
       * @return Boolean is equal
       */
      public function equals(loc:Location):Boolean {
         var equals:Boolean = false;
         if (loc != null) {
            equals = this._x == loc.x && this._y == loc.y; // && this._projection.srsCode == loc.projection.srsCode;
         }
         return equals;
      }

      /**
       * Create a Location from a string
       * @param str:String the string representing the coordinates
       * @param proj:ProjProjection the projection of the coordinates, default EPSG:4326
       *
       * @return Location the location.
       */
      public static function getLocationFromString(str:String, proj:Projection = null):Location {
         var pair:Array = str.split(",");
         return new Location(Number(pair[0]), Number(pair[1]), proj);
      }

   }
}